//
//  UITextField+YCTools.m
//  Pods
//
//  Created by Apple on 2022/11/2.
//

#import "UITextField+YCTools.h"
#import <objc/runtime.h>
#import "NSString+YCTools.h"

static char const * const YCMaxLengthProperty = "maxLength";
static char const * const YCMaxNumberProperty = "maxNumber";
static char const * const YCJustNumberProperty = "justNumber";
static char const * const YCMoneyTypeProperty = "moneyType";
static char const * const YCPointNumberProperty = "pointNumber";
static char const * const YCDisableSpecialCharactersProperty = "disableSpecialCharacters";

@implementation UITextField (YCTools)
@dynamic maxLength;
@dynamic disableEmoji;
@dynamic maxNumber;
@dynamic justNumber;
@dynamic moneyType;
@dynamic pointNumber;
@dynamic disableSpecialCharacters;

- (NSInteger)maxLength {
    return [objc_getAssociatedObject(self, YCMaxLengthProperty) integerValue];
}

- (void)setMaxLength:(NSInteger)maxLength {
    objc_setAssociatedObject(self, YCMaxLengthProperty, @(maxLength), OBJC_ASSOCIATION_ASSIGN);
    if (maxLength>0) {
        [self addTarget:self action:@selector(textFieldChange:) forControlEvents:UIControlEventEditingChanged];
        [self addTarget:self action:@selector(textFieldDidBegin:) forControlEvents:UIControlEventEditingDidBegin];
    }
}

- (CGFloat)maxNumber {
    return [objc_getAssociatedObject(self, YCMaxNumberProperty) doubleValue];
}

- (void)setMaxNumber:(CGFloat)maxNumber {
    objc_setAssociatedObject(self, YCMaxNumberProperty, @(maxNumber), OBJC_ASSOCIATION_ASSIGN);
    if (maxNumber>0) {
        [self addTarget:self action:@selector(textFieldChange:) forControlEvents:UIControlEventEditingChanged];
        [self addTarget:self action:@selector(textFieldDidBegin:) forControlEvents:UIControlEventEditingDidBegin];
    }
}

- (BOOL)justNumber {
    return [objc_getAssociatedObject(self, YCJustNumberProperty) boolValue];
}

- (void)setJustNumber:(BOOL)justNumber {
    objc_setAssociatedObject(self, YCJustNumberProperty, @(justNumber), OBJC_ASSOCIATION_ASSIGN);
    if (justNumber) {
        [self addTarget:self action:@selector(textFieldChange:) forControlEvents:UIControlEventEditingChanged];
        [self addTarget:self action:@selector(textFieldDidBegin:) forControlEvents:UIControlEventEditingDidBegin];
    }
}

- (BOOL)disableSpecialCharacters {
    return [objc_getAssociatedObject(self, YCDisableSpecialCharactersProperty) boolValue];
}

- (void)setDisableSpecialCharacters:(BOOL)disableSpecialCharacters {
    objc_setAssociatedObject(self, YCDisableSpecialCharactersProperty, @(disableSpecialCharacters), OBJC_ASSOCIATION_ASSIGN);
    if (disableSpecialCharacters) {
        [self addTarget:self action:@selector(textFieldChange:) forControlEvents:UIControlEventEditingChanged];
        [self addTarget:self action:@selector(textFieldDidBegin:) forControlEvents:UIControlEventEditingDidBegin];
    }
}

- (BOOL)moneyType {
    return [objc_getAssociatedObject(self, YCMoneyTypeProperty) boolValue];
}

- (void)setMoneyType:(BOOL)moneyType {
    objc_setAssociatedObject(self, YCMoneyTypeProperty, @(moneyType), OBJC_ASSOCIATION_ASSIGN);
    if (moneyType) {
        self.pointNumber = 2;
        [self addTarget:self action:@selector(textFieldChange:) forControlEvents:UIControlEventEditingChanged];
        [self addTarget:self action:@selector(textFieldDidBegin:) forControlEvents:UIControlEventEditingDidBegin];
    }
}

- (NSInteger)pointNumber {
    return [objc_getAssociatedObject(self, YCPointNumberProperty) integerValue];
}

- (void)setPointNumber:(NSInteger)pointNumber {
    objc_setAssociatedObject(self, YCPointNumberProperty, @(pointNumber), OBJC_ASSOCIATION_ASSIGN);
    if (pointNumber) {
        [self addTarget:self action:@selector(textFieldChange:) forControlEvents:UIControlEventEditingChanged];
        [self addTarget:self action:@selector(textFieldDidBegin:) forControlEvents:UIControlEventEditingDidBegin];
    }
}

static char kdisableEmoji;
- (BOOL)disableEmoji {
    return objc_getAssociatedObject(self, &kdisableEmoji);
}

-(void)setDisableEmoji:(BOOL)disableEmoji {
    objc_setAssociatedObject(self, &kdisableEmoji, @(disableEmoji), OBJC_ASSOCIATION_ASSIGN);
    if (disableEmoji) {
        [self addTarget:self action:@selector(textFieldChange:) forControlEvents:UIControlEventEditingChanged];
        [self addTarget:self action:@selector(textFieldDidBegin:) forControlEvents:UIControlEventEditingDidBegin];
    }
}

- (BOOL)justNumberCheck:(NSString *)text {
    NSCharacterSet* tmpSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
    int i = 0;
    NSString *tempStr = text;
    while (i < tempStr.length) {
        NSString * nowStr = [tempStr substringWithRange:NSMakeRange(i, 1)];
        NSRange range = [nowStr rangeOfCharacterFromSet:tmpSet];
        if (range.length == 0) {
            [self backText];
            return NO;
            break;
        }
        i++;
    }
    return YES;
}

- (BOOL)justMoneyNumberCheck:(NSString *)text {
    NSCharacterSet* tmpSet = [NSCharacterSet characterSetWithCharactersInString:@".0123456789"];
    int i = 0;
    NSString *tempStr = text;
    while (i < tempStr.length) {
        NSString * nowStr = [tempStr substringWithRange:NSMakeRange(i, 1)];
        NSRange range = [nowStr rangeOfCharacterFromSet:tmpSet];
        if (range.length == 0) {
            [self backText];
            return NO;
            break;
        }
        i++;
    }
    return YES;
}

- (void)textFieldDidBegin:(UITextField *)textField {
    [[NSUserDefaults standardUserDefaults] setValue:self.text forKey:@"kUserDefaults_TempText"];
}

- (void)textFieldChange:(UITextField *)textField {
    /**< 当输入中文时,只获取中文部分,过滤掉多余的字母 */
    if (self.maxLength > 0) {
        UITextRange *selectedRange = [textField markedTextRange];
        NSString * newText = [textField textInRange:selectedRange];
        if (newText.length > 0) {/**< 获取高亮部分 */
            return;
        }
        if(self.text.length > self.maxLength){
            [self backText];
        }
    }
    /// 限制只能输入这些
    if (self.justNumber && ![self justNumberCheck:self.text]) {
        return;
    }
    /// 表情过滤
    if (self.disableEmoji && ![self isNineKeyBoard:self.text] && ([self hasEmoji:self.text] || [self stringContainsEmoji:self.text])) {
        [self backText];
        return;
    }
    /// 过滤特殊字符
    if (self.disableSpecialCharacters && [self stringContainsSpecialString:self.text]) {
        [self backText];
        return;
    }
    /// 设置了限制数值
    if (self.maxNumber>0 && [self.text doubleValue] > self.maxNumber) {
        [self backText];
        return;
    }
    /// 小数点位数限制
    if (self.pointNumber>0 && [textField.text containsString:@"."]) {
        NSInteger flag=0;
        //小数点后需要限制的个数
        for (NSUInteger i = self.text.length-1; i >= 0; i--) {
            if ([self.text characterAtIndex:i] == '.') {
                if (flag > self.pointNumber) {
                    [self backText];
                    return;
                }
                break;
            }
            flag++;
        }
    }
    if (self.moneyType) {
        //限制只能输入这些
        if (![self justMoneyNumberCheck:self.text]) {
            return;
        }
        // 第一位为零输入除点外的，重置
        NSString *b = @"";
        if (textField.text.length>0) {
            b = [textField.text substringFromIndex:textField.text.length-1];
        }
        if (textField.text.length == 2 &&
            ![b isEqualToString:@"."] &&
            [textField.text intValue] == 0) {
            [self backText];
            return;
        }
        // 只允许输入一个小数点
        NSArray *ary = [self.text componentsSeparatedByString:@"."];
        if ([textField.text containsString:@"."] && ary.count>2) {
            [self backText];
            return;
        }
        // 小数点不能为第一位
        if ([self.text isEqualToString:@"."]) {
            [self backText];
            return;
        }
    }
    [[NSUserDefaults standardUserDefaults] setValue:self.text forKey:@"kUserDefaults_TempText"];
}

- (void)backText {
    NSString *text = [[NSUserDefaults standardUserDefaults] valueForKey:@"kUserDefaults_TempText"];
    self.text = text;
    [self endEditing:YES];
}

/// 是否包含特殊字符
- (BOOL)stringContainsSpecialString:(NSString *)string {
    //字符串
    NSString *specialStringStr = @"~,～,￥,#,&,*,<,>,《,》,(,),[,],{,},【,】,^,@,/,￡,¤,§,¨,「,」,『,』,￠,￢,￣,（,）,——,+,$,_,€,¥,？,?,｜,|,，,.,。,!,！,;,；,',‘,`,：,:,、,-,“,\", ";
    
    NSMutableArray *arry = [specialStringStr componentsSeparatedByString:@","].mutableCopy;
    [arry addObject:@","];
    
    if ([arry containsObject:string]) {
        return YES;
    }
    
    return NO;
}

/// 返回过滤特殊符号的字符串
- (NSString *)returnModifiedString:(NSString *)str {
    NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"~～￥#&*<>《》()[]{}【】^@/￡¤§¨「」『』￠￢￣（）—+$_€¥？?｜|，.。!！;；'‘`：:、-“\", "];
    NSString *modifiedString = [str stringByTrimmingCharactersInSet:set];
    
    return modifiedString;
}

/**
 * 判断字符串中是否存在emoji
 * @param string 字符串
 * @return YES(含有表情)
 */
- (BOOL)hasEmoji:(NSString*)string {
    NSString *pattern = @"[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]";
    
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
    BOOL isMatch = [pred evaluateWithObject:string];
    return isMatch;
}

/**
 判断是不是九宫格
 @param string  输入的字符
 @return YES(是九宫格拼音键盘)
 */
- (BOOL)isNineKeyBoard:(NSString*)string {
    NSString *other = @"➋➌➍➎➏➐➑➒";
    int len = (int)string.length;
    
    for (int i = 0; i < len; i++) {
        if (!([other rangeOfString:string].location != NSNotFound))
            return NO;
    }
    return YES;
}

- (BOOL)stringContainsEmoji:(NSString *)string {
    
    __block BOOL returnValue = NO;
    
    [string enumerateSubstringsInRange:NSMakeRange(0, [string length])
                               options:NSStringEnumerationByComposedCharacterSequences
                            usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
        const unichar high = [substring characterAtIndex: 0];
        
        // Surrogate pair (U+1D000-1F9FF)
        if (0xD800 <= high && high <= 0xDBFF) {
            const unichar low = [substring characterAtIndex: 1];
            const int codepoint = ((high - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
            
            if (0x1D000 <= codepoint && codepoint <= 0x1F9FF){
                returnValue = YES;
            }
            // Not surrogate pair (U+2100-27BF)
        } else {
            if (0x2100 <= high && high <= 0x27BF){
                returnValue = YES;
            }
        }
    }];
    
    return returnValue;
}

+ (UITextField *)textFieldWithFrame:(CGRect)frame
                          textColor:(UIColor *)textColor
                               font:(UIFont *)font
                        placeholder:(NSString *)placeholder {
    return [UITextField textFieldWithFrame:frame textColor:textColor font:font placeholder:placeholder textAlignment:NSTextAlignmentLeft keyboardType:UIKeyboardTypeDefault borderStyle:UITextBorderStyleNone leftView:[UIView new]];
}

+ (UITextField *)textFieldWithFrame:(CGRect)frame
                          textColor:(UIColor *)textColor
                               font:(UIFont *)font
                        placeholder:(NSString *)placeholder
                      textAlignment:(NSTextAlignment)textAlignment {
    return [UITextField textFieldWithFrame:frame textColor:textColor font:font placeholder:placeholder textAlignment:textAlignment keyboardType:UIKeyboardTypeDefault borderStyle:UITextBorderStyleNone leftView:[UIView new]];
}

+ (UITextField *)textFieldWithFrame:(CGRect)frame
                          textColor:(UIColor *)textColor
                               font:(UIFont *)font
                        placeholder:(NSString *)placeholder
                      textAlignment:(NSTextAlignment)textAlignment
                       keyboardType:(UIKeyboardType)keyboardType {
    return [UITextField textFieldWithFrame:frame  textColor:textColor font:font placeholder:placeholder textAlignment:textAlignment keyboardType:keyboardType borderStyle:UITextBorderStyleNone leftView:[UIView new]];
}

+ (UITextField *)textFieldWithFrame:(CGRect)frame
                          textColor:(UIColor *)textColor
                               font:(UIFont *)font
                        placeholder:(NSString *)placeholder
                      textAlignment:(NSTextAlignment)textAlignment
                       keyboardType:(UIKeyboardType)keyboardType
                        borderStyle:(UITextBorderStyle)borderStyle {
    return [UITextField textFieldWithFrame:frame textColor:textColor font:font placeholder:placeholder textAlignment:textAlignment keyboardType:keyboardType borderStyle:borderStyle leftView:[UIView new]];
}

+ (UITextField *)textFieldWithFrame:(CGRect)frame
                          textColor:(UIColor *)textColor
                               font:(UIFont *)font
                        placeholder:(NSString *)placeholder
                      textAlignment:(NSTextAlignment)textAlignment
                       keyboardType:(UIKeyboardType)keyboardType
                        borderStyle:(UITextBorderStyle)borderStyle
                           leftView:(UIView *)leftView {
    
    UITextField *textField = [[UITextField alloc] initWithFrame:frame];
    textField.textColor = textColor;
    textField.font = font;
    textField.placeholder = placeholder;
    textField.textAlignment = textAlignment;
    textField.keyboardType = keyboardType;
    textField.borderStyle = borderStyle;
    textField.clearButtonMode = UITextFieldViewModeNever;
    textField.leftView = leftView;
    textField.leftViewMode = UITextFieldViewModeAlways;
    NSMutableDictionary *attrs = [NSMutableDictionary dictionary]; // 创建属性字典
    attrs[NSForegroundColorAttributeName] = [UIColor colorWithRed:136/255.0 green:139/255.0 blue:153/255.0 alpha:1.0]; // 设置颜色
    NSAttributedString *attStr = [[NSAttributedString alloc] initWithString:placeholder attributes:attrs]; // 初始化富文本占位字符串
    textField.attributedPlaceholder = attStr;
    return textField;
}

@end
